package main

import (
	"encoding/json"
	"fmt"
)

// 复习结构体

type tmp struct {
	x int
	y int
}

type person struct {
	name string
	age  int
}

// 构造(结构体变量的)函数
func newPerson(name string, age int) person {
	return person{
		name: name,
		age:  age,
	}
}

// 方法
// 接收者使用对应类型的首字母小写
// 指定了接收者后
func (p person) dream(a string) {
	fmt.Printf("%s: have a %s\n", p.name, a)
}

func (p person) year1() {
	p.age++ // 此处的p是p1的副本，改的是副本
}

// 指针接收者
// 1.需要修改结构体变量的值时要使用接收者
// 2.结构体本身比较大，拷贝的内存开销比较大时也要使用指针接收者
// 3.保持一致性：如果有一个方法使用了指针接收者，其他的方法为了统一也要使用指针接收者
func (p *person) year2() {
	p.age++ // 此处的p是p1的副本，改的是副本
}

func main() {

	var b = tmp{
		10,
		20,
	}
	fmt.Println(b)

	var a = struct {
		x int
		y int
	}{1, 2}
	fmt.Println(a)

	var x int
	y := int8(10)
	fmt.Println(x, y)

	var p1 person
	p1.name = "偶"
	p1.age = 19

	p2 := person{"跑路", 18} // 结构体实例化
	fmt.Println(p1, p2)

	// 调用构造函数
	p4 := newPerson("开啊", 17)
	fmt.Println(p4)
	p1.dream("c")
	p2.dream("python")
	fmt.Println(p1.age)
	p1.year2()
	fmt.Println(p1.age)
	p2.year2()

	// 结构体嵌套
	type addr struct {
		province string
		city     string
	}

	type student struct {
		name string
		addr // 匿名嵌套别的结构体，就是使用类型名做名称
	}

	type point struct {
		X int `json:"x"`
		Y int `json:"y"`
	}
	po1 := point{100, 200}
	// 序列化
	bb, err := json.Marshal(po1)
	// 如果出错误了
	if err != nil {
		fmt.Println("序列化出错")
	}
	fmt.Println(string(bb))

	// 反序列化：由字符串--> Go中的结构体变量
	str1 := `{"mam":11,"li":20}`
	var po2 point // 造一个结构体变量，准备接受反序列化的值
	err = json.Unmarshal([]byte(str1), po2)
	if err != nil {
		fmt.Printf("unmarshal failed,err:%v\n", err)
	}
	fmt.Println(po2)

	// map
	m1 := map[int64]string{
		100: "哈哈哈",
		101: "噢噢噢噢",
		102: "呃呃呃",
	}

	name1 := m1[103]
	fmt.Println(name1) // 取不到就返回value的零值

	name2, ok := m1[200] // ok = true 表示有这个key,ok=false 表示没有这个key
	fmt.Println(name2, ok)

}
